//
//  ClipOfflineTool.swift
//  ANOASTORE
//
//  Created by hudan on 2025/5/27.
//  Copyright © 2025 zwb. All rights reserved.
//

// 切片重传

import UIKit

struct OutlineDBKey {
    static let TableName = "OUTLINE_FILE"
    
    static let kVouId = "vou_id"
    static let kOfflineDt = "offline_dt"
    static let kTemplateData = "template_data"
    static let kPicData = "pic_data"
    static let kPicDataDetails = "pic_data_details"
    static let kImgName = "img_name"
    static let kImgData = "img_data"
    static let kUpStatus = "up_status"
    static let kClipNum = "clip_num"
    static let kClipName = "clip_name"
    static let kXuHao = "xuhao"
    static let kClipFolder = "clip_folder"
    static let kFailReason = "fail_reason"
    static let kMenuName = "menu_nm"
    
    static let statusWait = "0"
    static let statusSuccess = "1"
    static let statusFail = "-1"
}

final class ClipOfflineTool {
    

    private init() {}
    static let shared = ClipOfflineTool()
    
    /// 切片数据
    private var dataArray = [OffLineModel]()
    
    /// 失败重试次数
    private var retryTimes = 0
    
    func openDB() {
        
        FMDBHelper.shared.openDB(dbname: "menu_Database.sqlite")
        
        let params = [OutlineDBKey.kVouId, OutlineDBKey.kOfflineDt, OutlineDBKey.kTemplateData,
                      OutlineDBKey.kPicData, OutlineDBKey.kPicDataDetails, OutlineDBKey.kImgName,
                      OutlineDBKey.kImgData, OutlineDBKey.kUpStatus, OutlineDBKey.kClipNum,
                      OutlineDBKey.kClipName, OutlineDBKey.kXuHao, OutlineDBKey.kClipFolder,
                      OutlineDBKey.kFailReason, OutlineDBKey.kMenuName]
        
        FMDBHelper.shared.creatTable(tableName: OutlineDBKey.TableName, params: params)
        
        // 更新切片上传新字段
        if !FMDBHelper.shared.database.columnExists(OutlineDBKey.kClipNum, inTableWithName: OutlineDBKey.TableName) {
            let alterStr = "ALTER TABLE \(OutlineDBKey.TableName) ADD \(OutlineDBKey.kClipNum) CHAR(30)"
            if FMDBHelper.shared.database.executeUpdate(alterStr, withArgumentsIn: []) {
                print("插入成功")
            } else {
                print("插入失败")
            }
        }
        
        if !FMDBHelper.shared.database.columnExists(OutlineDBKey.kClipName, inTableWithName: OutlineDBKey.TableName) {
            let alterStr = "ALTER TABLE \(OutlineDBKey.TableName) ADD \(OutlineDBKey.kClipName) CHAR(30)"
            if FMDBHelper.shared.database.executeUpdate(alterStr, withArgumentsIn: []) {
                print("插入成功")
            } else {
                print("插入失败")
            }
        }
        
        if !FMDBHelper.shared.database.columnExists(OutlineDBKey.kXuHao, inTableWithName: OutlineDBKey.TableName) {
            let alterStr = "ALTER TABLE \(OutlineDBKey.TableName) ADD \(OutlineDBKey.kXuHao) CHAR(5)"
            if FMDBHelper.shared.database.executeUpdate(alterStr, withArgumentsIn: []) {
                print("插入成功")
            } else {
                print("插入失败")
            }
        }
        
        if !FMDBHelper.shared.database.columnExists(OutlineDBKey.kClipFolder, inTableWithName: OutlineDBKey.TableName) {
            let alterStr = "ALTER TABLE \(OutlineDBKey.TableName) ADD \(OutlineDBKey.kClipFolder) CHAR(40)"
            if FMDBHelper.shared.database.executeUpdate(alterStr, withArgumentsIn: []) {
                print("插入成功")
            } else {
                print("插入失败")
            }
        }
        
        if !FMDBHelper.shared.database.columnExists(OutlineDBKey.kFailReason, inTableWithName: OutlineDBKey.TableName) {
            let alterStr = "ALTER TABLE \(OutlineDBKey.TableName) ADD \(OutlineDBKey.kFailReason) CHAR(200)"
            if FMDBHelper.shared.database.executeUpdate(alterStr, withArgumentsIn: []) {
                print("插入成功")
            } else {
                print("插入失败")
            }
        }
        
        if !FMDBHelper.shared.database.columnExists(OutlineDBKey.kMenuName, inTableWithName: OutlineDBKey.TableName) {
            let alterStr = "ALTER TABLE \(OutlineDBKey.TableName) ADD \(OutlineDBKey.kMenuName) CHAR(30)"
            if FMDBHelper.shared.database.executeUpdate(alterStr, withArgumentsIn: []) {
                print("插入成功")
            } else {
                print("插入失败")
            }
        }
    
        
        FMDBHelper.shared.delete(from: OutlineDBKey.TableName, where: OutlineDBKey.kUpStatus, equalto: OutlineDBKey.statusSuccess)
    }
    
    func updateUpSatatus(id: String, status: String) {
        FMDBHelper.shared.update(table: OutlineDBKey.TableName, set: [OutlineDBKey.kUpStatus], with: ["1"], where: "id", equalto: id)
    }
    
    func updateError(id: String, reason: String) {
        FMDBHelper.shared.update(table: OutlineDBKey.TableName, set: [OutlineDBKey.kUpStatus, OutlineDBKey.kFailReason], with: ["1", reason], where: "id", equalto: id)
    }
    
    /// 根据状态获取切片(status: 0:待上传/-1:上传失败)
    func getClip(status: String) -> [OffLineModel] {
        var tmpArr = [OffLineModel]()
        
        do {
            openDB()
            
            // 取待上传切片(up_status = 0), 失败切片不管, 失败的放在专门的失败切片列表页自己传
            let sql = "SELECT * FROM \(OutlineDBKey.TableName) WHERE \(OutlineDBKey.kUpStatus) = (?)"
            let resultSet = try FMDBHelper.shared.database.executeQuery(sql, values: [status])
              

            while resultSet.next() {
        
                if let id = resultSet.string(forColumn: "id"),
                   let offline_dt = resultSet.string(forColumn: OutlineDBKey.kOfflineDt),
                   let template_data = resultSet.string(forColumn: OutlineDBKey.kTemplateData),
                   let pic_data = resultSet.string(forColumn: OutlineDBKey.kPicData),
                   let pic_data_details = resultSet.string(forColumn: OutlineDBKey.kPicDataDetails),
                   let img_name = resultSet.string(forColumn: OutlineDBKey.kImgName),
                   let img_data = resultSet.data(forColumn: OutlineDBKey.kImgData),
                   let xuhao = resultSet.string(forColumn: OutlineDBKey.kXuHao),
                   let clip_num = resultSet.string(forColumn: OutlineDBKey.kClipNum),
                   let clip_name = resultSet.string(forColumn: OutlineDBKey.kClipName),
                   let clip_folder = resultSet.string(forColumn: OutlineDBKey.kClipFolder),
                   let fail_reason = resultSet.string(forColumn: OutlineDBKey.kFailReason),
                   let menu_nm = resultSet.string(forColumn: OutlineDBKey.kMenuName)
                {
                     
                    var onexx = VideoImg()
                    onexx.name = img_name
                    onexx.data = img_data
                    onexx.clipIndex = intTran(xuhao)
                    onexx.clipCount = intTran(clip_num)
                    onexx.clipName = clip_name
                    
                    if img_name.contains("jpg") || img_name.contains("png") {
                        onexx.type = .image
                    } else if img_name.contains("mp4") {
                        onexx.type = .video
                    } else {
                        onexx.type = .file
                    }
                    let onem = OffLineModel(id:id, offline_dt: offline_dt, template_data: template_data, pic_data: pic_data, pic_data_details: pic_data_details, image: onexx, clipFolder: clip_folder, failReason: fail_reason, menuName: menu_nm)
                    tmpArr.append(onem)
                }
            }
                         
        } catch {
            
        }
        
        return tmpArr
    }
    
    /// 检测是否有未上传切片
    func checkOfflineFile() {
        // 之前的还没传完先不取新的
        if dataArray.count > 0 {
            return
        }
                
        self.dataArray = getClip(status: "0")
        
        if self.dataArray.count > 0 {
            self.uploadOffFineAction()
        }
    }
    
    
    /// 上传切片
    private func uploadOffFineAction() {
    
        if self.dataArray.count > 0 {
            
            let onem = self.dataArray.first!
            
            uploadOne(model: onem) { [weak self] success, errorInfo in
                if success {
                    self?.updateUpSatatus(id: onem.id, status: "1")
                    self?.dataArray.removeFirst()
                    
                } else {
                    self?.retryTimes += 1
                    
                    if self?.retryTimes == 5 {
                        self?.retryTimes = 0
                        ClipOfflineTool.shared.updateError(id: onem.id, reason: errorInfo)
                        self?.dataArray.removeFirst()
                    }
                }
                
                self?.uploadOffFineAction()
            }
        }
    }
    
    
    /// 单个切片上传
    /// - Parameters:
    ///   - model: 切片 model
    ///   - complete: 结果回调
    func uploadOne(model: OffLineModel, complete: ((_ success: Bool, _ errorInfo: String) -> Void)?) {
        KSNetwork.shared.doRequest(
            API.temp(.tempUploadFileClipApi(file_name: model.image.name.unwrap,
                                            clip_num: model.image.clipCount.unwrap,
                                            xuhao: model.image.clipIndex.unwrap,
                                            pic_data: model.pic_data,
                                            pic_data_details: model.pic_data_details,
                                            templateData: model.template_data,
                                            file: model.image, clip_name: model.clipFolder)),
            showHud: false, successHandle: { (data:BaseResult<OperateResult>) in
            
                complete?(data.flag == TRUE, data.errorCombine.unwrap)
        })
    }
}
